using System;
using System.Linq;
using System.Collections.Generic;
using DevExpress.CodeRush.StructuralParser;
using CR.StyleCop.Utils;

namespace CR.StyleCop.Maintainability {
    public class UseBuiltInTypeAliasSearcher : BaseStyleCopIssueSearcher<ITypeReferenceExpression> {
        private static Dictionary<string, string> builtInTypeAlias;

        static UseBuiltInTypeAliasSearcher() {
            builtInTypeAlias = new Dictionary<string, string>();
            builtInTypeAlias.Add("Array", "array");
            builtInTypeAlias.Add("Boolean", "bool");
            builtInTypeAlias.Add("Byte", "byte");
            builtInTypeAlias.Add("Char", "char");
            builtInTypeAlias.Add("Decimal", "decimal");
            builtInTypeAlias.Add("Double", "double");
            builtInTypeAlias.Add("Int16", "short");
            builtInTypeAlias.Add("Int32", "int");
            builtInTypeAlias.Add("Int64", "long");
            builtInTypeAlias.Add("Object", "object");
            builtInTypeAlias.Add("SByte", "sbyte");
            builtInTypeAlias.Add("Single", "single");
            builtInTypeAlias.Add("String", "string");
            builtInTypeAlias.Add("UInt16", "ushort");
            builtInTypeAlias.Add("UInt32", "uint");
            builtInTypeAlias.Add("UInt64", "ulong");
        }

        public override IEnumerable<StyleCopIssue> FindIssues(IEnumerable<ITypeReferenceExpression> elements) {
            return elements.Where(e => IsBuiltInTypeAlias(e.Name)).Select(e => new StyleCopIssue {
                Element = e,
                IssueDescription = String.Format(CR.StyleCop.Resource.UseBuiltInTypeAliasSearcherIssueDescription, e.Name, GetTypeAlias(e.Name))
            });
        }

        private static bool IsBuiltInTypeAlias(string type) {
            return builtInTypeAlias.ContainsKey(type);
        }

        private static string GetTypeAlias(string type) {
            return builtInTypeAlias[type];
        }
    }
}
